using Circus.CodeEditor;
using Circus.Syntax.CodeCompletion;
using Circus.Syntax.Lexer;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
namespace Circus.Syntax
{
	[DesignerCategory("Code"), ToolboxItem(false)]
	public class SyntaxParser : Parser
	{
		protected class LexerState
		{
			private Hashtable hash;
			private LexerProc stateProc;
			public LexerProc StateProc
			{
				set
				{
					this.stateProc = value;
				}
			}
			public LexerState()
			{
				this.hash = new Hashtable();
			}
			public void Add(char[] chars, LexerProc proc)
			{
				for (int i = 0; i < chars.Length; i++)
				{
					char c = chars[i];
					this.hash[c] = proc;
				}
			}
			public LexerProc GetProc(char ch)
			{
				LexerProc lexerProc = (LexerProc)this.hash[ch];
				if (lexerProc == null)
				{
					lexerProc = this.stateProc;
				}
				return lexerProc;
			}
			public void Clear()
			{
				this.hash.Clear();
			}
		}
		private class LineNodeComparer : IComparer<SyntaxNode>
		{
			public int Compare(SyntaxNode x, SyntaxNode y)
			{
				Range range = x.Range;
				int y2 = y.Range.StartPoint.Y;
				return (y2 > range.StartPoint.Y && y2 <= range.EndPoint.Y) ? 0 : (range.StartPoint.Y - y2);
			}
		}
		private class PointNodeComparer : IComparer<SyntaxNode>
		{
			public int Compare(SyntaxNode x, SyntaxNode y)
			{
				Range range = x.Range;
				Point startPoint = y.Range.StartPoint;
				return ((startPoint.Y > range.StartPoint.Y || (startPoint.Y == range.StartPoint.Y && startPoint.X >= range.StartPoint.X)) && (startPoint.Y < range.EndPoint.Y || (startPoint.Y == range.EndPoint.Y && startPoint.X <= range.EndPoint.X))) ? 0 : (startPoint.Equals(range.StartPoint) ? 1 : ((range.StartPoint.Y == startPoint.Y) ? (range.StartPoint.X - startPoint.X) : (range.StartPoint.Y - startPoint.Y)));
			}
		}
		private class NodeComparer : IComparer<SyntaxNode>
		{
			public int Compare(SyntaxNode x, SyntaxNode y)
			{
				Range range = x.Range;
				Range range2 = y.Range;
				int num = range.StartPoint.Y - range2.StartPoint.Y;
				if (num == 0)
				{
					num = range.StartPoint.X - range2.StartPoint.X;
				}
				if (num == 0)
				{
					num = range.EndPoint.Y - range2.EndPoint.Y;
				}
				if (num == 0)
				{
					num = range.EndPoint.X - range2.EndPoint.X;
				}
				return num;
			}
		}
		private class ListMemberComparer : IComparer<IComparable>
		{
			private SyntaxParser owner;
			public ListMemberComparer(SyntaxParser owner)
			{
				this.owner = owner;
			}
			public int Compare(IComparable x, IComparable y)
			{
				return string.Compare(((ListMember)x).Name, ((ListMember)y).Name, !this.owner.CaseSensitive);
			}

        }
		private Hashtable lexerStates;
		private bool useScheme;
		private SyntaxOptions options;
		private SyntaxTree syntaxTree;
		private IList<SyntaxNode> stackNodes;
		private ICodeCompletionRepository repository;
		private char[] codeCompletionChars;
		private char[] codeCompletionStopChars;
		private char[] smartFormatChars;
		private char[] autoIndentChars;
		private int parseInterval;
		protected IComparer<SyntaxNode> lineNodeComparer;
		protected IComparer<SyntaxNode> pointNodeComparer;
		protected IComparer<SyntaxNode> nodeComparer;
		protected IComparer<IComparable> listMemberComparer;
		protected SyntaxParser.LexerState lexerState;
		private SyntaxParser threadParser;
		protected bool aborted;
		private string fileName = string.Empty;

	    [Description("Occurs when \"SyntaxParser\" text content is fully parsed.")]
	    public event EventHandler TextReparsed;
		[Browsable(false)]
		public override string XmlScheme
		{
			get
			{
				return base.XmlScheme;
			}
			set
			{
				base.XmlScheme = value;
			}
		}
		protected virtual bool InSyntaxUpdate
		{
			get
			{
				return this.stackNodes != null && this.stackNodes.Count > 0;
			}
		}
		protected virtual SyntaxParser ThreadParser
		{
			get
			{
				if (this.threadParser == null)
				{
					this.threadParser = this.CreateThreadParser();
				}
				return this.threadParser;
			}
		}
		[Browsable(true), Description("Gets or sets a flags determining syntax parsing and formatting behavior."), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Editor("QWhale.Design.FlagEnumerationEditor, QWhale.Design", typeof(UITypeEditor))]
		public virtual SyntaxOptions Options
		{
			get
			{
				return this.options;
			}
			set
			{
				if (this.options != value)
				{
					this.options = value;
					this.OnOptionsChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual IExpressionEvaluator ExpressionEvaluator
		{
			get
			{
				return null;
			}
			set
			{
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual SyntaxTree SyntaxTree
		{
			get
			{
				return this.syntaxTree;
			}
			set
			{
				if (this.syntaxTree != value)
				{
					this.syntaxTree = value;
					this.OnSyntaxTreeChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual ICodeCompletionRepository CompletionRepository
		{
			get
			{
				if (this.repository == null)
				{
					this.repository = this.CreateRepository();
				}
				return this.repository;
			}
			set
			{
				if (this.repository != value)
				{
					this.repository = value;
					this.OnRepositoryChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual string FileName
		{
			get
			{
				return this.fileName;
			}
			set
			{
				this.fileName = value;
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual ICodeSnippetsProvider CodeSnippets
		{
			get
			{
				return this.CompletionRepository.GetCodeSnippets(this.Scheme.FileType);
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual bool CaseSensitive
		{
			get
			{
				return false;
			}
		}
		[DefaultValue(false), Description("Gets or sets a boolean value that indicates whether \"ISyntaxParser\" should perform lexical analysis based on it's rules rather than using internal method.")]
		public virtual bool UseScheme
		{
			get
			{
				return this.useScheme;
			}
			set
			{
				if (this.useScheme != value)
				{
					this.useScheme = value;
					this.Update();
				}
			}
		}
		[Description("Gets or sets a collection of characters that initializes a code completion procedure when typing.")]
		public virtual char[] CodeCompletionChars
		{
			get
			{
				return this.codeCompletionChars;
			}
			set
			{
				if (this.codeCompletionChars != value)
				{
					this.codeCompletionChars = value;
					this.OnCodeCompletionCharsChanged();
				}
			}
		}
		[Description("Gets or sets a collection of characters that finalizes a code completion procedure when typing.")]
		public virtual char[] CodeCompletionStopChars
		{
			get
			{
				return this.codeCompletionStopChars;
			}
			set
			{
				if (this.codeCompletionStopChars != value)
				{
					this.codeCompletionStopChars = value;
					this.OnCodeCompletionStopCharsChanged();
				}
			}
		}
		[Description("Gets or sets a collection of characters that initializes an indentation procedure when typing.")]
		public virtual char[] AutoIndentChars
		{
			get
			{
				return this.autoIndentChars;
			}
			set
			{
				if (this.autoIndentChars != value)
				{
					this.autoIndentChars = value;
					this.OnAutoIndentCharsChanged();
				}
			}
		}
		[Description("Gets or sets a collection of characters that initializes a smart formatting procedure when typing.")]
		public virtual char[] SmartFormatChars
		{
			get
			{
				return this.smartFormatChars;
			}
			set
			{
				if (this.smartFormatChars != value)
				{
					this.smartFormatChars = value;
					this.OnSmartFormatCharsChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual bool Aborted
		{
			get
			{
				return this.aborted;
			}
			set
			{
				this.aborted = value;
			}
		}
		[Description("specifies delay repasing should trigger after any change in the editor.")]
		public virtual int ParseInterval
		{
			get
			{
				return this.parseInterval;
			}
			set
			{
				if (this.parseInterval != value)
				{
					this.parseInterval = value;
					this.OnParseIntervalChanged();
				}
			}
		}
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual bool SupportsThread
		{
			get
			{
				return (this.options & SyntaxOptions.WorkInThread) != SyntaxOptions.None && (this.Site == null || !this.Site.DesignMode);
			}
		}
		protected virtual SyntaxParser.LexerState GetLexerState(int state)
		{
			SyntaxParser.LexerState lexerState = (SyntaxParser.LexerState)this.lexerStates[state];
			if (lexerState == null)
			{
				lexerState = new SyntaxParser.LexerState();
				this.lexerStates[state] = lexerState;
			}
			return lexerState;
		}
		protected virtual void OnOptionsChanged()
		{
		}
		protected virtual void OnSyntaxTreeChanged()
		{
		}
		protected virtual void OnRepositoryChanged()
		{
		}
		protected virtual void OnCodeCompletionCharsChanged()
		{
		}
		protected virtual void OnCodeCompletionStopCharsChanged()
		{
		}
		protected virtual void OnAutoIndentCharsChanged()
		{
		}
		protected virtual void OnSmartFormatCharsChanged()
		{
		}
		protected virtual void OnParseIntervalChanged()
		{
		}
		protected override void OnXmlSchemeChanged()
		{
			this.InitLanguage();
		}
		public SyntaxParser()
		{
			this.lexerStates = new Hashtable();
			this.syntaxTree = new SyntaxTree();
			this.lineNodeComparer = new SyntaxParser.LineNodeComparer();
			this.pointNodeComparer = new SyntaxParser.PointNodeComparer();
			this.listMemberComparer = new SyntaxParser.ListMemberComparer(this);
			this.nodeComparer = new SyntaxParser.NodeComparer();
			this.InitLexer();
		}
		public virtual bool ShouldSerializeCodeCompletionChars()
		{
			return this.codeCompletionChars.Length != 0;
		}
		public virtual bool ShouldSerializeCodeCompletionStopChars()
		{
			return this.codeCompletionStopChars.Length != 0;
		}
		public virtual bool ShouldSerializeSmartFormatChars()
		{
			return this.smartFormatChars.Length != 0;
		}
		public virtual bool ShouldSerializeAutoIndentChars()
		{
			return this.autoIndentChars.Length != 0;
		}
		protected virtual void LexSpace()
		{
			this.currentPos++;
			int length = this.source.Length;
			while (this.currentPos < length)
			{
				char c = this.source[this.currentPos];
				if (c < '\0' || c > ' ')
				{
					break;
				}
				this.currentPos++;
			}
		}
		protected virtual bool IsFirstIdentChar(char ch)
		{
			return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || (ch >= 'À' && ch <= 'Ɏ') || (ch >= 'ß' && ch <= 'ʯ');
		}
		protected virtual bool IsIdentChar(char ch)
		{
			return this.IsFirstIdentChar(ch) || (ch >= '0' && ch <= '9');
		}
		protected virtual void LexIdent()
		{
			this.currentPos++;
			int length = this.source.Length;
			while (this.currentPos < length)
			{
				char c = this.source[this.currentPos];
				if (!this.IsIdentChar(this.source[this.currentPos]))
				{
					break;
				}
				this.currentPos++;
			}
		}
		protected virtual void LexNum()
		{
			this.currentPos++;
			int length = this.source.Length;
			while (this.currentPos < length)
			{
				char c = this.source[this.currentPos];
				if (c < '0' || c > '9')
				{
					break;
				}
				this.currentPos++;
			}
		}
		protected void RegisterLexerProc(int state, LexerProc proc)
		{
			this.GetLexerState(state).StateProc = proc;
		}
		protected void RegisterLexerProc(int state, char[] chars, LexerProc proc)
		{
			this.GetLexerState(state).Add(chars, proc);
		}
		protected void RegisterLexerProc(int state, char ch, LexerProc proc)
		{
			this.RegisterLexerProc(state, new char[]
			{
				ch
			}, proc);
		}
		protected void RegisterLexerProc(int state, char startChar, char endChar, LexerProc proc)
		{
			char[] array = new char[(int)(endChar - startChar + '\u0001')];
			for (char c = startChar; c <= endChar; c += '\u0001')
			{
				array[(int)(c - startChar)] = c;
			}
			this.RegisterLexerProc(state, array, proc);
		}
		protected void AddStyle(string name, Color color, Color backColor, FontStyle fontStyle, bool plainText)
		{
			LexStyle lexStyle = this.Scheme.Styles.AddLexStyle();
			lexStyle.Name = name;
			lexStyle.FontStyle = fontStyle;
			if (color != Color.Empty)
			{
				lexStyle.ForeColor = color;
			}
			if (backColor != Color.Empty)
			{
				lexStyle.BackColor = backColor;
			}
			lexStyle.PlainText = plainText;
		}
		protected void AddStyle(string name, Color color, FontStyle fontStyle, bool plainText)
		{
			this.AddStyle(name, color, Color.Empty, fontStyle, plainText);
		}
		protected void AddStyle(string name, Color color, FontStyle fontStyle)
		{
			this.AddStyle(name, color, Color.Empty, fontStyle, false);
		}
		protected void AddStyle(string name, Color color)
		{
			this.AddStyle(name, color, Color.Empty, FontStyle.Regular, false);
		}
		protected virtual void InitDefaultStyles()
		{
			this.AddStyle(StringConsts.IdentsInternalName, SyntaxConsts.DefaultIndentsForeColor);
			this.AddStyle(StringConsts.NumbersInternalName, SyntaxConsts.DefaultNumbersForeColor);
			this.AddStyle(StringConsts.ReswordsInternalName, SyntaxConsts.DefaultReswordForeColor);
			this.AddStyle(StringConsts.CommentsInternalName, SyntaxConsts.DefaultCommentsForeColor, FontStyle.Regular, true);
			this.AddStyle(StringConsts.XMLCommentsInternalName, SyntaxConsts.DefaultXmlCommentsForeColor, FontStyle.Regular, false);
			this.AddStyle(StringConsts.SymbolsInternalName, SyntaxConsts.DefaultSymbolForeColor);
			this.AddStyle(StringConsts.WhiteSpaceInternalName, Color.Empty);
			this.AddStyle(StringConsts.StringsInternalName, SyntaxConsts.DefaultStringsForeColor, FontStyle.Regular, true);
			this.AddStyle(StringConsts.DirectivesInternalName, SyntaxConsts.DefaultDirectivesForeColor);
			this.AddStyle(StringConsts.HTMLParamsInternalName, SyntaxConsts.DefaultHtmlParamsForeColor);
			this.AddStyle(StringConsts.SyntaxErrorsInternalName, SyntaxConsts.DefaultSyntaxErrorsForeColor);
			this.AddStyle(StringConsts.CodeSnippetsInternalName, Color.Black, SyntaxConsts.DefaultCodeSnippetBackColor, FontStyle.Regular, false);
		}
		protected virtual void InitCopyright()
		{
			this.Scheme.Author = "Quantum Whale, LLC.";
			this.Scheme.Copyright = "Copyright (c) 2004 - 2014 Quantum Whale LLC.";
		}
		protected virtual void InitLanguage()
		{
		}
		protected virtual void InitStyles()
		{
		}
		protected char CurChar()
		{
			return (this.currentPos < this.source.Length) ? this.source[this.currentPos] : '\0';
		}
		protected virtual void InitLexer()
		{
			this.lexerStates.Clear();
			this.InitCopyright();
			this.InitLanguage();
			this.InitStyles();
			this.StateChanged();
		}
		protected override void StateChanged()
		{
			this.lexerState = this.GetLexerState(this.State);
		}
		protected virtual int GetLexerStyle(int token)
		{
			return token;
		}
		protected virtual void ParseToken(LexerProc proc, ref int pos, ref int token, ref int currentPos, ref int tokenPos, ref int style, ref int state)
		{
			this.currentPos = pos;
			this.tokenPos = pos;
			this.State = state;
			if (this.IsValidToken(token))
			{
				this.prevToken = token;
			}
			token = proc();
			style = this.GetLexerStyle(token);
			pos = this.currentPos;
			currentPos = this.currentPos;
			state = this.State;
		}
		public override int ParseText(int state, int line, string s, ref int pos, ref int len, ref int token)
		{
			if (this.aborted)
			{
				throw new StopParseException();
			}
			int result;
			if (this.useScheme)
			{
				result = base.ParseText(state, line, s, ref pos, ref len, ref token);
			}
			else
			{
				this.State = state;
				this.lineIndex = line;
				this.source = s;
				int length = s.Length;
				LexerProc lexerProc = null;
				while (pos < length)
				{
					lexerProc = this.lexerState.GetProc(s[pos]);
					if (lexerProc != null)
					{
						break;
					}
					pos++;
				}
				if (lexerProc != null)
				{
					this.currentPos = pos;
					this.tokenPos = pos;
					token = lexerProc();
					len = this.currentPos - pos;
				}
				result = this.State;
			}
			return result;
		}
		public override int ParseText(int state, int line, string str, ref StringItemInfo[] colorData)
		{
			int result;
			if (this.useScheme)
			{
				result = base.ParseText(state, line, str, ref colorData);
			}
			else
			{
				this.State = state;
				this.lineIndex = line;
				this.source = str;
				int num = -1;
				int length = str.Length;
				int i = 0;
				while (i < length)
				{
					int num2 = i;
					LexerProc proc = this.lexerState.GetProc(str[i]);
					if (proc == null)
					{
						colorData[i].Data = 0;
						colorData[i].TextStyle = TextStyle.None;
						i++;
					}
					else
					{
						if (num2 != i)
						{
							for (int j = i; j < num2; j++)
							{
								colorData[j].Data = 0;
								colorData[j].TextStyle = TextStyle.None;
							}
						}
						num2 = i;
						int num3 = 0;
						this.ParseToken(proc, ref i, ref num, ref this.currentPos, ref this.tokenPos, ref num3, ref state);
						for (int j = num2; j < Math.Min(i, length); j++)
						{
							colorData[j].Data = (byte)(num3 + 1);
							colorData[j].TextStyle = TextStyle.None;
						}
					}
				}
				base.OnTextParsed(str, ref colorData);
				result = state;
			}
			return result;
		}
		public override void Reset()
		{
			base.Reset();
			this.syntaxTree.Clear();
		}
		protected virtual SyntaxParser CreateThreadParser()
		{
			SyntaxParser syntaxParser = Activator.CreateInstance(base.GetType()) as SyntaxParser;
			syntaxParser.Strings = new StringList();
			return syntaxParser;
		}
		protected virtual void AssignParser(SyntaxParser parser)
		{
			parser.UseScheme = this.UseScheme;
			parser.Options = this.Options;
			parser.ExpressionEvaluator = (((this.Options & SyntaxOptions.EvaluateConditionals) != SyntaxOptions.None) ? this.ExpressionEvaluator : null);
			parser.CodeCompletionChars = this.codeCompletionChars;
		}
		protected virtual SyntaxNode GetNodeForCodeCompletion(ref Point position)
		{
			return this.GetNodeAt(position);
		}
		protected virtual void BeforeLoad()
		{
			if (this.Strings == null)
			{
				this.Strings = new StringList();
			}
		}
		protected virtual void AfterLoad()
		{
			this.ReparseText();
		}
		protected virtual void Outline(IList<Range> ranges, SyntaxNode node, int level)
		{
			if ((node.Options & SyntaxNodeOptions.Outlining) != SyntaxNodeOptions.None)
			{
				Point start = node.Range.StartPoint;
				SyntaxAttribute syntaxAttribute = node.FindAttribute(SyntaxConsts.DeclarationScope);
				if (syntaxAttribute != null)
				{
					start = syntaxAttribute.Position;
				}
				syntaxAttribute = node.FindAttribute(SyntaxConsts.OutlineText);
				ranges.Add(new OutlineRange(start, node.Range.EndPoint, level, (syntaxAttribute != null) ? ((string)syntaxAttribute.Value) : "..."));
				level++;
			}
			if (node.HasChildren)
			{
				foreach (SyntaxNode current in node.ChildList)
				{
					this.Outline(ranges, current, level);
				}
			}
		}
		protected int PartialCompare(ListMember x, ListMember y, int maxLen, bool caseSensitive)
		{
			if (maxLen == -1)
			{
				maxLen = Math.Min(x.Name.Length, y.Name.Length);
			}
			return string.Compare(x.Name, 0, y.Name, 0, maxLen, !caseSensitive);
		}
		protected int PartialCompare(ListMember x, ListMember y)
		{
			return this.PartialCompare(x, y, x.Name.Length, false);
		}
		protected bool FindPartial(SortList<IComparable> members, ListMember member, out int idx)
		{
			members.FindFirst(member, out idx, this.listMemberComparer);
			bool result;
			if (idx >= 0 && idx < members.Count && this.PartialCompare(member, (ListMember)members[idx], member.Name.Length, false) == 0)
			{
				if (this.CaseSensitive)
				{
					for (int i = idx; i < members.Count; i++)
					{
						if (this.PartialCompare(member, (ListMember)members[i], member.Name.Length, true) == 0)
						{
							idx = i;
							break;
						}
						if (this.PartialCompare(member, (ListMember)members[i], -1, false) != 0)
						{
							break;
						}
					}
				}
				result = true;
			}
			else
			{
				result = false;
			}
			return result;
		}
		protected virtual bool FindMember(string name, ListMembers members, out int idx)
		{
			idx = -1;
			bool result;
			if (name == string.Empty)
			{
				result = false;
			}
			else
			{
                SortList<IComparable> sortList = new SortList<IComparable>();
				for (int i = 0; i < members.Count; i++)
				{
					sortList.Add(new ListMember
					{
						Name = members[i].Name,
						Priority = i
					});
				}
				sortList.Sort(this.listMemberComparer);
				ListMember listMember = new ListMember();
				listMember.Name = name;
				if (this.FindPartial(sortList, listMember, out idx))
				{
					idx = ((ListMember)sortList[idx]).Priority;
					result = (idx == sortList.Count - 1 || this.PartialCompare(listMember, (ListMember)sortList[idx + 1]) != 0);
				}
				else
				{
					while (name != string.Empty)
					{
						name = name.Substring(0, name.Length - 1);
						if (name != string.Empty)
						{
							listMember.Name = name;
							if (this.FindPartial(sortList, listMember, out idx))
							{
								idx = ((ListMember)sortList[idx]).Priority;
								result = false;
								return result;
							}
						}
					}
					idx = -1;
					result = false;
				}
			}
			return result;
		}
        protected virtual void GetSyntaxErrors(SyntaxErrors errors, SyntaxNode node)
		{
			if (node.HasErrors)
			{
				foreach (SyntaxError current in node.ErrorList)
				{
					errors.Add(current);
				}
			}
			if (node.HasChildren)
			{
				foreach (SyntaxNode current2 in node.ChildList)
				{
					this.GetSyntaxErrors(errors, current2);
				}
			}
		}
		protected virtual ParameterInfo CreateParameterInfo()
		{
			return new ParameterInfo();
		}
		protected virtual ListMembers CreateListMembers()
		{
			return new ListMembers();
		}
		protected virtual void SortMembers(ListMembers members)
		{
			members.Sort(this.listMemberComparer);
		}
		protected virtual bool GetSmartIndent(SyntaxNode node, int index, ref int indent)
		{
			bool flag = (node.Options & SyntaxNodeOptions.Indentation) != SyntaxNodeOptions.None || (node.Options & SyntaxNodeOptions.BackIndentation) != SyntaxNodeOptions.None || (node.Options & SyntaxNodeOptions.KeepIndentation) != SyntaxNodeOptions.None;
			if (flag)
			{
				if ((node.Options & SyntaxNodeOptions.BackIndentation) == SyntaxNodeOptions.None && (node.Options & SyntaxNodeOptions.KeepIndentation) == SyntaxNodeOptions.None)
				{
					indent = ((indent < 0) ? 1 : (indent + 1));
				}
			}
			return flag;
		}
		protected virtual int GetSmartIndent(SyntaxNodes nodes, int index, bool autoIndent)
		{
			int num = -1;
			SyntaxNode syntaxNode = null;
			if (nodes != null)
			{
				foreach (SyntaxNode syntaxNode2 in nodes)
				{
					if (this.GetSmartIndent(syntaxNode2, index, ref num))
					{
						syntaxNode = syntaxNode2;
					}
					if (syntaxNode2.Position.Y == index && syntaxNode2 != this.syntaxTree.Root)
					{
						break;
					}
				}
			}
			else
			{
				SyntaxNode syntaxNode2 = this.syntaxTree.Root;
				SyntaxNode obj = new SyntaxNode(new Point(0, index), string.Empty);
				while (syntaxNode2 != null)
				{
					if (this.GetSmartIndent(syntaxNode2, index, ref num))
					{
						syntaxNode = syntaxNode2;
					}
					if (syntaxNode2.Position.Y == index && syntaxNode2 != this.syntaxTree.Root)
					{
						break;
					}
					syntaxNode2 = syntaxNode2.FindNode(obj, this.lineNodeComparer);
				}
			}
			if (!autoIndent && num >= 0 && syntaxNode != null)
			{
				num = syntaxNode.GetIndent(index, num);
			}
			return num;
		}
		public virtual void Prepare(string fileName, IStringList lines, SyntaxTree syntaxTree, bool useThread)
		{
			if (useThread)
			{
				SyntaxParser syntaxParser = this.ThreadParser;
				syntaxParser.FileName = fileName;
				syntaxParser.Strings.Clear();
				foreach (string current in lines)
				{
					syntaxParser.Strings.Add(current);
				}
				if (syntaxTree != null)
				{
					syntaxParser.SyntaxTree.Root.Assign(syntaxTree.Root);
				}
			}
			else
			{
				this.FileName = fileName;
				this.Strings = lines;
			}
		}
		public virtual void ReparseText(bool useThread, int first, int last)
		{
			if (useThread)
			{
				SyntaxParser syntaxParser = this.ThreadParser;
				try
				{
					this.AssignParser(syntaxParser);
					syntaxParser.Aborted = false;
					syntaxParser.ReparseText();
				}
				catch (StopParseException)
				{
				}
			}
			else
			{
				this.Aborted = false;
				this.ReparseText();
			}
		}
		public virtual void ReparseText(bool useThread)
		{
			this.ReparseText(useThread, 0, int.MaxValue);
		}
		public virtual void FinishParsing()
		{
			if (this.threadParser != null)
			{
				this.syntaxTree.Root = this.threadParser.SyntaxTree.Root;
				this.threadParser.SyntaxTree.Root = new SyntaxNode();
				this.OnTextParsed();
			}
		}
		public virtual void StopParsing()
		{
			if (this.threadParser != null)
			{
				this.threadParser.Abort();
			}
		}
		public virtual void Abort()
		{
			this.aborted = true;
		}
		public virtual void BlockDeleting(Rectangle rect)
		{
			this.SyntaxTree.BlockDeleting(rect);
		}
		public virtual void PositionChanged(int x, int y, int deltaX, int deltaY)
		{
			this.SyntaxTree.PositionChanged(x, y, deltaX, deltaY);
		}
		public virtual void OnTextParsed()
		{
			if (this.TextReparsed != null)
			{
				this.TextReparsed(this, EventArgs.Empty);
			}
		}
		public virtual void ReparseText()
		{
			if (!this.InSyntaxUpdate)
			{
				this.OnTextParsed();
			}
		}
		public virtual bool ReparseBlock(Point position)
		{
			return false;
		}
		public virtual bool ReparseBlock(ref Point position, string text, out SyntaxNode node, CodeCompletionType completionType)
		{
			bool result = this.ReparseBlock(position);
			node = this.GetNodeAt(position);
			return result;
		}
		public virtual int Outline(IList<Range> ranges)
		{
			this.Outline(ranges, this.syntaxTree.Root, 0);
			return ranges.Count;
		}
		public virtual int GetSmartIndent(int index, bool autoIndent)
		{
			bool flag;
			return this.GetSmartIndent(index, autoIndent, out flag);
		}
		public virtual string GetSmartIndentString(int index, bool autoIndent, bool useSpaces, int spacesInTab)
		{
			return null;
		}
		public virtual int GetSmartIndent(int index, bool autoIndent, out bool actualPosition)
		{
			int num = -1;
			SyntaxNode syntaxNode = this.syntaxTree.Root;
			SyntaxNode syntaxNode2 = null;
			SyntaxNode obj = new SyntaxNode(new Point(0, index), string.Empty);
			actualPosition = false;
			while (syntaxNode != null)
			{
				if ((syntaxNode.Options & SyntaxNodeOptions.Indentation) != SyntaxNodeOptions.None || (syntaxNode.Options & SyntaxNodeOptions.BackIndentation) != SyntaxNodeOptions.None || (syntaxNode.Options & SyntaxNodeOptions.KeepIndentation) != SyntaxNodeOptions.None)
				{
					if ((syntaxNode.Options & SyntaxNodeOptions.BackIndentation) == SyntaxNodeOptions.None && (syntaxNode.Options & SyntaxNodeOptions.KeepIndentation) == SyntaxNodeOptions.None)
					{
						num = ((num < 0) ? 1 : (num + 1));
					}
					syntaxNode2 = syntaxNode;
				}
				if (syntaxNode.Position.Y == index && syntaxNode != this.syntaxTree.Root)
				{
					break;
				}
				syntaxNode = syntaxNode.FindNode(obj, this.lineNodeComparer);
			}
			if (!autoIndent && num >= 0 && syntaxNode2 != null)
			{
				num = syntaxNode2.GetIndent(index, num, out actualPosition);
			}
			return num;
		}
		public virtual int SmartFormatLine(int index, string text, StringItemInfo[] textData, TextUndoList operations)
		{
			bool flag;
			return this.SmartFormatLine(index, text, textData, operations, out flag);
		}
		public virtual int SmartFormatLine(int index, string text, StringItemInfo[] textData, TextUndoList operations, out bool actualPosition)
		{
			return this.GetSmartIndent(index, false, out actualPosition);
		}
		public virtual bool SmartFormat(ref Point pos, bool useSpace, int spacesInTab, TextUndoList operations)
		{
			return false;
		}
		public virtual bool SmartFormat(ref Point start, ref Point end, bool useSpaces, int spacesInTab, TextUndoList operations)
		{
			return false;
		}
        public virtual int GetSyntaxErrors(SyntaxErrors errors)
		{
			this.GetSyntaxErrors(errors, this.syntaxTree.Root);
			return errors.Count;
		}
		public virtual bool SupportsCodeCompletionFiltering(CodeCompletionType completionType)
		{
			bool result;
			switch (completionType)
			{
			case CodeCompletionType.CompleteWord:
			case CodeCompletionType.ListMembers:
				break;
			default:
				if (completionType != CodeCompletionType.SpecialListMembers)
				{
					result = false;
					return result;
				}
				break;
			}
			result = true;
			return result;
		}
		public virtual void CodeCompletion(string text, StringItemInfo[] textData, Point position, bool useThread, CodeCompletionArgs e)
		{
			if (useThread)
			{
				SyntaxParser syntaxParser = this.ThreadParser;
				try
				{
					syntaxParser.Aborted = false;
					this.AssignParser(syntaxParser);
					syntaxParser.CompletionRepository = this.CompletionRepository;
					syntaxParser.CodeCompletion(text, textData, position, e);
				}
				catch (StopParseException)
				{
				}
			}
			else
			{
				this.CodeCompletion(text, textData, position, e);
			}
		}
		public virtual void CodeCompletion(string text, StringItemInfo[] textData, Point position, CodeCompletionArgs e)
		{
			CodeCompletionType completionType = this.GetCompletionType(e);
			if (completionType != CodeCompletionType.None)
			{
				switch (completionType)
				{
				case CodeCompletionType.CompleteWord:
				case CodeCompletionType.ListMembers:
				case CodeCompletionType.ParameterInfo:
				case CodeCompletionType.SpecialListMembers:
				{
					Point point = position;
					SyntaxNode nodeForCodeCompletion;
					if (e.NeedReparse)
					{
						this.ReparseBlock(ref position, text, out nodeForCodeCompletion, completionType);
					}
					else
					{
						nodeForCodeCompletion = this.GetNodeForCodeCompletion(ref position);
					}
					if (nodeForCodeCompletion != null)
					{
						text = this.RemovePlainText(text, textData);
						ListMembers listMembers = null;
						CodeCompletionScope codeCompletionScope = CodeCompletionScope.None;
						Point point2 = new Point(-1, -1);
						Point point3 = position;
						string empty = string.Empty;
						if (completionType == CodeCompletionType.ParameterInfo)
						{
							int paramIndex;
							int num;
							object obj = this.CompletionRepository.GetMethodType(text, nodeForCodeCompletion, ref empty, ref point3, ref point2, out paramIndex, out num, out codeCompletionScope);
							if (obj != null)
							{
								listMembers = this.CreateParameterInfo();
								listMembers.ShowParams = true;
								listMembers.ShowQualifiers = false;
								this.CompletionRepository.FillMember(listMembers, obj, empty, paramIndex, codeCompletionScope);
							}
							e.ToolTip = true;
						}
						else
						{
							object obj = (completionType == CodeCompletionType.SpecialListMembers) ? this.CompletionRepository.GetSpecialMemberType(text, nodeForCodeCompletion, ref empty, ref point3, ref point2, out codeCompletionScope) : this.CompletionRepository.GetMemberType(text, nodeForCodeCompletion, ref empty, ref point3, ref point2, out codeCompletionScope);
							bool flag = false;
							if (obj != null)
							{
								flag = ((codeCompletionScope & CodeCompletionScope.Delegate) != CodeCompletionScope.None);
								if (flag)
								{
									listMembers = this.CreateParameterInfo();
									listMembers.ShowParams = false;
									listMembers.ShowQualifiers = false;
								}
								else
								{
									listMembers = this.CreateListMembers();
									listMembers.ShowDescriptions = true;
									listMembers.ShowResults = false;
									listMembers.ShowQualifiers = false;
								}
								int num2 = -1;
								this.CompletionRepository.FillMembers(nodeForCodeCompletion, point3, listMembers, obj, empty, codeCompletionScope, ref num2);
								this.SortMembers(listMembers);
								if (!flag && listMembers.Count > 0)
								{
									int num3 = 0;
									if (num2 >= 0 || this.FindMember(empty, listMembers, out num3))
									{
										if (completionType == CodeCompletionType.CompleteWord && (num2 >= 0 || !point3.Equals(point)))
										{
											e.SelIndex = ((num2 >= 0) ? num2 : num3);
										}
									}
									listMembers.SelIndex = ((num2 >= 0) ? num2 : num3);
								}
							}
							e.ToolTip = flag;
						}
						e.StartPosition = point3;
						e.DisplayPosition = point3;
						if (listMembers != null)
						{
							CodeCompletionType codeCompletionType = completionType;
							if (codeCompletionType != CodeCompletionType.ParameterInfo)
							{
								if (codeCompletionType != CodeCompletionType.SpecialListMembers)
								{
									if (point3.Equals(position))
									{
										e.EndPosition = ((point2.Y >= 0) ? point2 : new Point(point3.X + ((e.SelIndex >= 0) ? empty.Length : 0), point3.Y));
									}
									else
									{
										e.EndPosition = ((point2.Y >= 0) ? point2 : new Point(point3.X + empty.Length, point3.Y));
									}
								}
								else
								{
									e.EndPosition = point2;
								}
							}
							else
							{
								e.EndPosition = point2;
							}
						}
						e.Provider = listMembers;
					}
					break;
				}
				case CodeCompletionType.QuickInfo:
				{
					SyntaxNode nodeForCodeCompletion;
					if (e.NeedReparse)
					{
						this.ReparseBlock(ref position, text, out nodeForCodeCompletion, completionType);
					}
					else
					{
						nodeForCodeCompletion = this.GetNodeForCodeCompletion(ref position);
					}
					if (nodeForCodeCompletion != null)
					{
						text = this.RemovePlainText(text, textData);
						object obj = this.CompletionRepository.FindDeclaration(text, nodeForCodeCompletion, new Point(position.X + 1, position.Y));
						if (obj != null)
						{
							string description = this.CompletionRepository.GetDescription(this.CreateListMembers(), (obj is SyntaxNode) ? nodeForCodeCompletion : null, obj, SyntaxConsts.SummaryDescription, true);
							if (description != null && description != string.Empty)
							{
								QuickInfo quickInfo = new QuickInfo();
								quickInfo.Text = description;
								e.ToolTip = true;
								e.Provider = quickInfo;
							}
						}
					}
					break;
				}
				case CodeCompletionType.CodeSnippets:
					e.Provider = this.CodeSnippets;
					break;
				}
				e.CompletionType = completionType;
			}
			switch (completionType)
			{
			case CodeCompletionType.CodeSnippets:
			case CodeCompletionType.CompleteComment:
				e.Interval = 0;
				goto IL_46F;
			}
			e.Interval = SyntaxConsts.DefaultCompletionDelay;
			IL_46F:
			e.NeedShow = (e.Provider != null && e.Provider.Count > 0);
		}
		public virtual bool ProcessAutoComplete(string text, Point position, out string code)
		{
			code = string.Empty;
			return false;
		}
		public virtual string GetSingleLineComment()
		{
			return string.Empty;
		}
		public virtual bool GetMultiLineComment(out string start, out string end)
		{
			start = string.Empty;
			end = string.Empty;
			return false;
		}
		public virtual SyntaxNode GetAutoFormatNode(Point position, bool extended, out Point startPt)
		{
			startPt = Point.Empty;
			return null;
		}
		public virtual SyntaxNode GetNodeAt(Point position)
		{
			return this.SyntaxTree.FindNode(new SyntaxNode(position, string.Empty), this.pointNodeComparer);
		}
		public virtual Range GetRangeAt(Point position)
		{
			SyntaxNode nodeAt = this.GetNodeAt(position);
			return (nodeAt != null) ? nodeAt.Range : null;
		}
		public virtual bool IsDeclaration(SyntaxNode node)
		{
			return false;
		}
		public virtual object FindDeclaration(string text, Point position)
		{
			SyntaxNode nodeAt = this.GetNodeAt(position);
			return (nodeAt != null) ? this.CompletionRepository.FindDeclaration(text, nodeAt, position) : null;
		}
		public virtual int FindReferences(SyntaxNode node, SyntaxNodes references)
		{
			return this.CompletionRepository.FindReferences(node, references);
		}
		public virtual bool IsCodeCompletionChar(char ch, byte style, ref int interval)
		{
			bool result;
			if (style > 0 && this.Scheme.IsPlainText((int)(style - 1)))
			{
				result = false;
			}
			else
			{
				bool flag = Array.IndexOf<char>(this.codeCompletionChars, ch) >= 0;
				if (flag && this.GetCompletionType(ch) == CodeCompletionType.CompleteComment)
				{
					interval = 0;
				}
				result = flag;
			}
			return result;
		}
		public virtual void ResetOptions()
		{
			this.Options = SyntaxOptions.None;
		}
		public virtual void ResetCodeCompletionChars()
		{
			this.CodeCompletionChars = new char[0];
		}
		public virtual void ResetCodeCompletionStopChars()
		{
			this.CodeCompletionStopChars = new char[0];
		}
		public virtual void ResetAutoIndentChars()
		{
			this.AutoIndentChars = new char[0];
		}
		public virtual void ResetSmartFormatChars()
		{
			this.SmartFormatChars = new char[0];
		}
		public virtual void ResetParseInterval()
		{
			this.ParseInterval = SyntaxConsts.DefaultParseInterval;
		}
		public virtual bool IsContentDivider(int index)
		{
			return false;
		}
		public virtual ICodeCompletionRepository CreateRepository()
		{
			return new CodeCompletionRepository(this.CaseSensitive, this.SyntaxTree);
		}
		public virtual CodeCompletionType GetCompletionType(CodeCompletionArgs e)
		{
			return (e.CompletionType == CodeCompletionType.None) ? this.GetCompletionType(e.KeyChar) : e.CompletionType;
		}
		public virtual CodeCompletionType GetCompletionType(char ch)
		{
			return CodeCompletionType.None;
		}
		public void SaveSyntaxTree()
		{
			if (this.stackNodes == null)
			{
				this.stackNodes = new List<SyntaxNode>();
			}
			this.stackNodes.Add(this.syntaxTree.Root);
			this.syntaxTree.Root = (this.syntaxTree.Root.Clone() as SyntaxNode);
		}
		public virtual void RestoreSyntaxTree()
		{
			if (this.InSyntaxUpdate)
			{
				this.syntaxTree.Root = this.stackNodes[this.stackNodes.Count - 1];
				this.stackNodes.RemoveAt(this.stackNodes.Count - 1);
			}
		}
	
	}
}
